#include "case.h"


int fd;//用于TCP协议的全局变量
int fd_udp;//用于UDP协议的全局变量


//接收信息
void * recv_msg(void * arg)
{
    int nu;
    char rebuf[100];
    int fd_arg = *(int *)arg;
    while(1)
    {
        bzero(rebuf,sizeof(rebuf));
        nu = recv(fd_arg,rebuf,sizeof(rebuf),0);
        if (nu == 0)
        {
            break;
        }
        else if(nu > 0)
        {
            printf("The message is:%s",rebuf);
        }
        
    }
}


//接收UDP广播
void * udp_recv(void * arg)
{
    int udp_arg = *(int *)arg;
    char buf[100] = {0};
    struct sockaddr_in ipmsg; 
    socklen_t len = sizeof(ipmsg);
    char ipbuf[16] = {0};
    while(1)
    {
        bzero(buf,100);
        bzero(ipbuf,16);
        recvfrom(udp_arg,buf,100,0,(struct sockaddr*)&ipmsg,&len);
        inet_ntop(AF_INET,&ipmsg.sin_addr,ipbuf,16);
        printf("From sender:%s\nMsg:%s\n",ipbuf,buf);
    }
}


//接收文件
void * recv_sfile(void * arg)
{
    int fdm = *(int *)arg;
    char a[100];
    char buf[100];
    FILE *fp;
    int ret = 3;
    while(1)
    {
        int b = 1;
        char num[2] = {0};
        bzero(a,100);
        bzero(buf,100);
    
        if(b == 1)
        {
            ret = recv(fdm,a,100,0);
			
			if (a[0]=='.')//收到的是文件
			{	

				printf("请选择是否接收信息？y接收\tn拒绝\n");
				scanf("%c",num);
				getchar();
				if (strcmp(num,"n") == 0)//拒收
				{
					printf("无视文件成功！！\n");

			
				}
				
				if(strcmp(num,"y") == 0)//接收
				{		
					printf("555\n");
                    char *ch =strrchr(a,'/')+1; //提取文件名
					fp=fopen(ch,"w");//以可写的方式打开文件
					if (fp==NULL)
					{
						printf("open file\n");
						
					}
					
					b++;
				}
			
			}

			if (b==2)//接收文件名后执行
			{	
				printf("等待接收文件\n");
				recv(fdm,buf,100,0);
				fwrite(buf,10,10,fp);
				printf("buf%s\n",buf);
				printf("传输文件成功\n");
				fclose(fp);

			}

            if (a[0] != '.')
            {
                printf("%s\n",a);
            }
            
        }
        if (ret == 0)
        {
            printf("断开连接\n");
            exit(1);
        }
            
    }
    
}


//发送文件
void file_trans()
{

    char file[100];
    char file_path[200];
    bzero(file,sizeof(file));
    bzero(file_path,sizeof(file_path));
    printf("请在当前路径下输入需传输文件的路径：");
    scanf("%s",file);
    sprintf(file_path,"./%s",file);

    FILE * fp = fopen(file_path,"r+");
    if (fp == NULL)
    {
        perror("fopen fail");
        exit(1);
    }

    struct file_info filesend;
    bzero(&filesend,sizeof(filesend));
    strcpy(filesend.filename,file_path);
    filesend.pid = getpid();
    stat(file_path,&filesend.msg);
    
    printf("file path:%s\tfile size:%ld\n",filesend.filename,filesend.msg.st_size);
    send(fd,&filesend,sizeof(filesend),0);
    sleep(2);
    char dil[1024];
    int i;
    while(1)
    {
        bzero(dil,sizeof(dil));
        i = fread(dil,1024,1,fp);
        if (i == 0)
        {
            printf("上传成功\n");
            break;
        }
        

        send(fd,dil,sizeof(dil),0);
        
        
    }

    fclose(fp);
    return;
}


int main(int argc, char * argv[])
{
    if (argc != 3)
    {
        printf("Using rule:%s\tip\tport\n",argv[0]);
        exit(1);
    }
    
    
///////////////////////////////////////TCP//////////////////////////////////////////    
    
    fd = socket(AF_INET,SOCK_STREAM,0);//创建套接字

    
    struct sockaddr_in server;//定义结构体
    bzero(&server,sizeof(server));//清空结构体
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));


    inet_pton(AF_INET,argv[1],&server.sin_addr.s_addr);
    int	ret = connect(fd,(struct sockaddr *)&server,sizeof(server));
	if(ret < 0)
	{
		perror("connect fail");
		exit(1);
		
	}
////////////////////////////////////////////////////////////////////////////////////    


///////////////////////////////////////UDP//////////////////////////////////////////    
    int ret_a;

	//创建数据报式套接字（用于UDP）
	int fd_udp = socket(AF_INET,SOCK_DGRAM,0);
	
	//设置套接字的属性，SO_REUSERADDR 允许立刻重复使用IP和端口
	int on = 1;
	setsockopt(fd_udp,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	
	//准备好服务器地址结构体（IPV4地址结构体）
	struct sockaddr_in srvaddr;
	bzero(&srvaddr,sizeof(srvaddr));
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons(atoi(argv[2]));
	srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	

	//绑定IP+PORT
	ret_a = bind(fd_udp,(struct sockaddr *)&srvaddr,sizeof(srvaddr));
	if(ret_a < 0)
	{
		perror("bind fail");
		exit(1);	
	}
    
////////////////////////////////////////////////////////////////////////////////////    


//接收信息的线程
    pthread_t tid1;
    int b = pthread_create(&tid1,NULL,recv_msg,(void *)&fd);
    if (b != 0)
    {
        printf("fail to creat the pthread\n");
    }


//接收UDP广播的线程
    pthread_t tid2;
    int h = pthread_create(&tid2,NULL,udp_recv,(void *)&fd_udp);
    if (h != 0)
    {
        printf("fail to creat the pthread\n");
    }


//接收文件的线程
    pthread_t tid3;
    int t = pthread_create(&tid3,NULL,recv_sfile,&fd);
    if (t != 0)
    {
        printf("fail to creat the pthread\n");
    }
    

	char buf[100];
	
	while(1)
	{
		bzero(buf, 100);
        scanf("%s",buf);
        //getchar();
		
        if (strcmp(buf,".") == 0)
        {
            //bzero(buf,sizeof(buf));
            file_trans();
        }
        
        send(fd, buf, strlen(buf), 0);
        while(getchar()!='\n');
	}


    

    



    return 0;
}